package com.eureka.client.demo.ribbon;


import com.eureka.client.demo.lancher.ServiceLancherHandlerChain;
import io.jmnarloch.spring.cloud.ribbon.support.RibbonFilterContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;

@Aspect
@Component
@Slf4j
public class FeignRibbonFilterInterceptor {


    @Autowired
    private ServiceLancherHandlerChain serviceLancherHandlerChain;

    /**
     * 定义一个公共的切点
     */
    @Pointcut("@within(org.springframework.cloud.openfeign.FeignClient)")
    public void performance() {
    }

    private String getFeignClientName(JoinPoint joinPoint){
        Object obj = joinPoint.getTarget();
        Class[] classes = obj.getClass().getInterfaces();
        for (Class clz: classes
                ) {
            Annotation annotation = clz.getAnnotation(FeignClient.class);
            if (annotation!= null && annotation instanceof FeignClient){
                FeignClient feignClient = (FeignClient) annotation;
                return feignClient.name();
            }
        }
        return null;
    }

    /**
     * 目标方法执行之前调用
     */
    @Before("performance()")
    public void silenceCellPhone(JoinPoint joinPoint) {
        String clientName = this.getFeignClientName(joinPoint);
        if (StringUtils.isBlank(clientName)){
            return;
        }
        serviceLancherHandlerChain.handle(clientName);
        log.debug("before=========clientName:{}",clientName);
        log.debug("目标方法执行之前调用");
    }

    /**
     * 目标方法执行之后调用
     */
    @After("performance()")
    public void takeSeats() {
        RibbonFilterContextHolder.clearCurrentContext();
    }

}
